package game;

import java.awt.Color;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

import game.maps.Brick;
import game.maps.Map;
import game.network.ClientThread;
import game.network.Packet;
import game.network.ServerThread;

public class Model {

	private Player myPlayer = null; 
	
	private Player enemyPlayer = null;
	
	private InfoBar infoBar;
	
	private boolean started = false;
	
	private Runnable networkThread;
	
	private List<Sprite> sprites = Collections.synchronizedList(new ArrayList<Sprite>());
	
	private List<Sprite> networkSprites = Collections.synchronizedList(new ArrayList<Sprite>());
	
	int lastPlayedX = 0;
	int lastPlayedY = 0;
	
	   
   String role = null;
   String serverIP = null;
   String music = null;
	
	public List<Sprite> getSprites() {
		return sprites;
	}
	
	public void initialize(Map map, Movement movement) {
		if (music.equals("on")) Audio.startMusic();
		myPlayer = new Player(30, 30, 30, 30, Color.BLUE);
		sprites.add(myPlayer);
		sprites.addAll(map.getSprites());
		movement.registerForMovement(myPlayer);
	}

	public Model() {
		
	   Properties props = new Properties();

	   try {
		   props.load(new FileInputStream("network.properties"));
		   role = props.getProperty("role");
		   serverIP = props.getProperty("serverIP");
		   music = props.getProperty("music");
		  		   	
	   }catch(IOException e){
		   e.printStackTrace();
	   }
	   
	   infoBar = new InfoBar("You", "Opponent", 10, 10);

		if (role.equals("server")) {
			networkThread = new ServerThread(this);
		}
		else {
			networkThread = new ClientThread(this, serverIP);
		}
	}
	
	public boolean isNetworkWorking() {
		return started;
	}
	
	public void startNetwork() {
		started = true;
		new Thread(networkThread).start();
	}
	
	public void stopNetwork() {
		started = false;
	}
	
	public void setMyCoordinates(int x, int y) {
		myPlayer.setCoordinates(x, y);
	}
	
	public void setEnemyCoordinates(int x, int y) {
		if (enemyPlayer == null) {
					
			enemyPlayer = new Player(x, y, 30, 30, Color.GREEN);
			sprites.add(enemyPlayer);
		}
		else {
			enemyPlayer.setCoordinates(x, y);
		}
	}
	
	public Player getEnemyPlayer() {
		return enemyPlayer;
	}
	
	public ArrayList<Collision> collides(Sprite sprite, int x,int y,int x1,int y1,int newx,int newy,int newx1,int newy1) {
		
		ArrayList<Collision> collisions = new ArrayList<Collision>();
		int horDirection = Integer.signum(newx - x);
		int vertDirection = Integer.signum(newy - y);
//		System.out.println(horDirection + " " + vertDirection);
		
		synchronized(sprites) {
			for (Sprite s : sprites) {
				
				if (sprite == s) continue;
				
				int tx = x;
				int ty = y;
				int tx1 = x1;
				int ty1 = y1;
	//			System.out.println("--");
				while (tx!=newx || ty!=newy) {
	//				System.out.println(horDirection + " " + vertDirection + " " + tx + " " + ty + " " + newx + " " + newy + " " +x + " " + y);
					tx+= horDirection;
					ty+= vertDirection;
					tx1+=horDirection;
					ty1+=vertDirection;
					Direction side = Collision.getCollision(s.getX(), s.getY(), s.getX1(), s.getY1(), tx, ty, tx1, ty1);
					if (side!=null) {
						Collision collision = new Collision(s, side);
						collisions.add(collision);
	//					System.out.println("COLLISION " + side);
						break;
					}
				}
			}
		}
		
		return collisions;
	}
	
	public Player getMyPlayer() {
		return myPlayer;
	}
	public InfoBar getInfoBar(){
		return infoBar;
	}

	public Packet getPacket() {
		
		List<Integer> bulletX = new ArrayList<Integer>();
		List<Integer> bulletY = new ArrayList<Integer>();
		synchronized(sprites) {
			for (Sprite s: sprites){
				if (s instanceof Bullet){
					bulletX.add(s.getX());
					bulletY.add(s.getY());
				}
			}
		}
		
		int enemyLife;
		if (enemyPlayer==null) enemyLife = 0;
		else enemyLife = enemyPlayer.getLife();
		Packet packet = new Packet(myPlayer.getX(), myPlayer.getY(), enemyLife, bulletX, bulletY);
		return packet;
	}
	
	public List<Sprite> getNetworkSprites(){
		return networkSprites;
	}
	
	public void setPacket(Packet packet){
		if (packet == null) throw new NullPointerException("packet is null");
		setEnemyCoordinates(packet.getPlayerX(), packet.getPlayerY());
		myPlayer.setLife(packet.getPlayerLife());
		networkSprites.clear();
		for (int i=0; i<packet.getBulletX().size(); i++){
			int x = packet.getBulletX().get(i);
			int y = packet.getBulletY().get(i);
			networkSprites.add(new Brick(x, y, 4, 4, Color.BLACK));
		}
	}
}
